package com.tanhua.commons.template;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.pojo.IMessage;
import com.tanhua.commons.properties.HuanXinProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class HuanXinTemplate {
    private HuanXinProperties properties;
    /**环信令牌，每次向环信发请求，都需要携带此令牌；否则不能调用环信接口*/
    private String token;
    /**令牌的过期时间，存储的是毫秒值*/
    private long expire = 0;
    /**环信的服务地址*/
    private String huanXinUrl;
    /**Rest工具，用于向环信发送RESTful请求，调用环信接口*/
    private RestTemplate restTemplate = new RestTemplate();

    public HuanXinTemplate(HuanXinProperties properties) {
        this.properties = properties;
        this.huanXinUrl = properties.getServerUrl() + "/" + properties.getOrgName() + "/" + properties.getAppName();
    }

    private String getToken() {
        if (token == null || System.currentTimeMillis() >= expire) {

            String url = huanXinUrl + "/token";

            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json");

            Map<String, Object> body = new HashMap<>();
            body.put("grant_type", "client_credentials");
            body.put("client_id", properties.getClientId());
            body.put("client_secret", properties.getClientSecret());

            HttpEntity<Map> httpEntity = new HttpEntity<>(body, headers);

            ResponseEntity<Map> response = restTemplate.postForEntity(url, httpEntity, Map.class);
            if (response.getStatusCodeValue() == 200) {
                Map result = response.getBody();
                token = (String) result.get("access_token");
                int expiresIn = (int) result.get("expires_in");
                expire = System.currentTimeMillis() + expiresIn * 1000;

                log.info("【环信】获取token成功，token:{},有效期到:{}", token, new Date(expire));
            } else {
                log.error("【环信】获取token失败", response);
            }
        }
        return token;
    }

    /**
     * 注册环信用户
     *
     * @param username 用户名
     * @param password 密码
     * @return 是否注册成功
     */
    public boolean register(String username, String password) {
        String url = huanXinUrl + "/users";

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Authorization", "Bearer " + getToken());
        httpHeaders.add("Content-Type", "application/json");

        Map<String, Object> params = new HashMap<>();
        params.put("username", username);
        params.put("password", password);

        HttpEntity<Map> httpEntity = new HttpEntity<>(params, httpHeaders);

        ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);

        boolean success = response.getStatusCode().value() == 200;
        if (success) {
            log.info("【环信】注册用户成功，username:{}, password:{}", username, password);
        } else {
            log.warn("【环信】注册用户失败，username:{}, password:{}, 注册结果：{}", username, password, response);
        }

        return success;
    }

    /**
     * 添加好友
     *
     * @return 是否添加成功
     */
    public boolean addContact(String username, String friend) {
        String url = huanXinUrl + "/users/" + username + "/contacts/users/" + friend;

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Type", "application/json");
        httpHeaders.add("Authorization", "Bearer " + getToken());

        HttpEntity entity = new HttpEntity(httpHeaders);

        ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

        boolean success = response.getStatusCode().value() == 200;
        if (success) {
            log.info("【环信】添加好友成功，username:{}, friend:{}", username, friend);
        } else {
            log.warn("【环信】添加好友失败，username:{}, friend:{}, 注册结果：{}", username, friend, response);
        }
        return success;
    }

    /**
     * 发送消息
     *
     * @return 是否发送成功
     */
    public boolean sendMessage(String targetUser, IMessage message) {
        String url = huanXinUrl + "/messages";

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("Authorization", "Bearer " + getToken());

        Map<String, Object> body = new HashMap<>();
        body.put("target_type", "users");
        body.put("target", new String[]{targetUser});

        Map<String, Object> msg = new HashMap<>();
        msg.put("type", "txt");
        msg.put("msg", JSON.toJSONString(message));

        body.put("msg", msg);

        HttpEntity<Map> entity = new HttpEntity<>(body, headers);

        ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

        boolean success = response.getStatusCode().value() == 200;
        if (success) {
            log.info("【环信】发送消息成功, from: {}, to: {}, message: {}", message.getUserId(), targetUser, message);
        } else {
            log.error("【环信】发送消息失败, from: {}, to: {}, message: {}, 结果: {}", message.getNickname(), targetUser, message, response);
        }
        return success;
    }
}